#include <vector>
#include <cstdio>
#include <algorithm>
using namespace std;

int S[100005];

struct node {
	int u, v;
	int w;
	node(int ui, int vi, int wi) {
		u = ui;
		v = vi;
		w = wi;
	}
};

vector<node> E;

int getf(int x) {
	if (S[x] == x) return x;
	return S[x] = getf(S[x]);
}

void merge(int x, int y) {
	int a = getf(x), b = getf(y);
	if (a != b) {
		S[a] = b;
		S[x] = b;
	}
}

bool cmp(node x, node y) {
	return x.w < y.w;
}

int main() {
	int n, r;
	int x, y;
	scanf("%d", &n);
	for (int i = 0; i <= n; ++i) {
		S[i] = i;
	}
	for (int i = 1; i <= n;  ++i) {
		for (int j = 1; j <= n; ++j) {
			scanf("%d", &x);
			E.push_back(node(i, j, x));
		}
	}

	scanf("%d", &r);
	for (int i = 1; i <= r; ++i) {
		scanf("%d %d", &x, &y);
		merge(x, y);
	}

	sort(E.begin(), E.end(), cmp);
	int index = 1;
	unsigned np = 0;
	int ans = 0;
	while (1) {
		int af = getf(1);
		for (int i = 2; i <= n; ++i) {
			if (getf(i) != af) goto CALC;
		}
		break;
		CALC:
		if (np >= E.size()) {
			ans = -1;
			break;
		}
		node now = E[np++];
		if (getf(now.u) == getf(now.v)) continue;
		++index;
		ans += now.w;
		merge(now.u, now.v);
	}

	printf("%d\n", ans);
	return 0;
}
